﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Controls.LiveControl
{
    public partial class WpfGdiScreen : UserControl
    {
        private Bitmap Screen { get; set; }
        private ScreenStatus _screenStatus;
        public WpfGdiScreen()
        {
            InitializeComponent();
            Screen = new Bitmap(1, 1);
            _screenStatus = ScreenStatus.FullScreen;

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
        }
          private Rectangle _srcRectangle;
        public void OnlyShowProc(Rectangle srcRectangle, ScreenStatus status)
        {
            _srcRectangle = srcRectangle;
            _screenStatus = status;
        }

        public void ShowFullScreen()
        {
            _screenStatus = ScreenStatus.FullScreen;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            switch (_screenStatus)
            {
                case ScreenStatus.FullScreen:
                    e.Graphics.DrawImage(Screen, new Rectangle(Point.Empty, this.Size));
                    break;
                case ScreenStatus.OnlyShowProcAndFit:
                    e.Graphics.DrawImage(Screen, new Rectangle(Point.Empty, this.Size), _srcRectangle, GraphicsUnit.Pixel);
                    break;
                case ScreenStatus.OnlyShowProcNotFit:
                    e.Graphics.FillRectangle(Brushes.Gray, new Rectangle(Point.Empty, this.Size));

                    e.Graphics.DrawImage(Screen, GetScreenRectangle(_srcRectangle), _srcRectangle, GraphicsUnit.Pixel);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

        }

        private RectangleF GetScreenRectangle(Rectangle srcRectangle)
        {
            var ratioX = Width/(float) Screen.Width;
            var ratioY = Height/(float) Screen.Height;
            var retRect = new RectangleF(srcRectangle.X*ratioX, srcRectangle.Y*ratioY, srcRectangle.Width*ratioX,
                srcRectangle.Height*ratioY);
            return retRect;
        }

        private RectangleF GetScreenRectangleTemp(Rectangle srcRectangle)
        {
            var ratioX = Width / (float)Screen.Width;
            var ratioY = Height / (float)Screen.Height;
            //统一缩放比例会更好看，不会有压缩感
            ratioY = ratioX;

            //控件中心点坐标
            float ctrCenterX = Width / (float)2;
            float ctrCenterY = Height / (float)2;

            //转换后的窗体中心点坐标
            float covHalfWidth = srcRectangle.Width * ratioX / (float)2;
            float covHalfHeight = srcRectangle.Height * ratioY / (float)2;

            float tempRatioX = ctrCenterX/ covHalfWidth;
            float tempRatioY = (ctrCenterY - 50) / covHalfHeight; // 上下留了50个像素用于放菜单
            //取两个比例中小的那个
            float ratioBigger = tempRatioY > tempRatioX ? tempRatioX : tempRatioY;
            // 太大了也不好看，最大比例不能超过1.2倍
            float MaxRatio = 1.2f;
            ratioBigger = ratioBigger > MaxRatio ? MaxRatio : ratioBigger;
            //放大点
            //float ratioBigger = 1.2f;
            float biggerHalfWidth = covHalfWidth * ratioBigger;
            float biggerHalfHeight = covHalfHeight * ratioBigger;
            

            //左上角坐标
            float left = ctrCenterX - biggerHalfWidth;
            float top = ctrCenterY - biggerHalfHeight;

            var retRect = new RectangleF(left, top, 2.0f * biggerHalfWidth, 2.0f * biggerHalfHeight);
            return retRect;
        }

        private readonly Pen _pen = new Pen(Color.Magenta, 2.0f);

        public void Draw(Image image, Rectangle region, bool flagShowRegionOutlines = false)
        {
            if (Screen.Width * Screen.Height < region.Width * region.Height)
            {
                Screen = new Bitmap(region.Width, region.Height);
            }
            

            var gfx = Graphics.FromImage(Screen);
            gfx.DrawImageUnscaled(image, region);
            if (flagShowRegionOutlines)
            {
                var gRegion = this.CreateGraphics();
                gRegion.DrawRectangle(_pen, region);
                gRegion.Dispose();
            }
            this.Invalidate();
        }

        public MouseEventArgs ReAlignPos(MouseEventArgs e)
        {
            MouseEventArgs tMouseEventArgs;
            switch (_screenStatus)
            {
                case ScreenStatus.FullScreen:
                    return e;
                case ScreenStatus.OnlyShowProcAndFit:
                    tMouseEventArgs = e;
                    break;
                case ScreenStatus.OnlyShowProcNotFit:
                    tMouseEventArgs = GetNotFitAlign(e);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }


            return tMouseEventArgs;
        }

        private MouseEventArgs GetNotFitAlign(MouseEventArgs mouseEventArgs)
        {
            return mouseEventArgs;
        }
    }
}
